import sys
import requests
from lxml import etree
import mysql.connector
from mysql.connector import Error
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QLineEdit, QPushButton, QLabel, QTableWidget, QTableWidgetItem, QMessageBox, QComboBox
import re
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
import ttkthemes
from PyQt5.QtCore import Qt, QPropertyAnimation, QEasingCurve
from PyQt5.QtGui import QPalette, QColor, QFont
from PyQt5.QtWidgets import QGraphicsDropShadowEffect, QFrame
from PyQt5.QtChart import QChart, QChartView, QPieSeries, QBarSet, QBarSeries, QValueAxis, QBarCategoryAxis
from PyQt5.QtCore import QTimer, QPropertyAnimation, QEasingCurve
from PyQt5.QtGui import QPainter, QGradient, QLinearGradient, QColor
# 连接MySQL数据库
def create_database_connection():
    try:
        # 连接到MySQL数据库
        conn = mysql.connector.connect(
            host='localhost',          # 数据库主机
            user='root',               # 数据库用户名
            password='123456',  # 数据库密码
            database='goods'   # 目标数据库名
        )
        if conn.is_connected():
            return conn
    except Error as e:
        QMessageBox.critical(None, "数据库连接失败", f"无法连接到数据库: {e}")
        return None


# 创建商品信息表
def create_table_if_not_exists():
    conn = create_database_connection()
    if conn is not None:
        cursor = conn.cursor()
        cursor.execute(''' 
            CREATE TABLE IF NOT EXISTS goods (
                id INT AUTO_INCREMENT PRIMARY KEY,
                title VARCHAR(255),
                price VARCHAR(50),
                shop VARCHAR(255),
                good_url VARCHAR(255),
                comment_num VARCHAR(50),
                comment_url VARCHAR(255)
            )
        ''')
        
        # 创建历史记录表
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS search_history (
                id INT AUTO_INCREMENT PRIMARY KEY,
                search_word VARCHAR(255),
                search_time DATETIME,
                page_num INT,
                results_count INT
            )
        ''')
        conn.commit()
        conn.close()


# 插入商品信息到数据库
def insert_goods_to_db(goods):
    conn = create_database_connection()
    if conn is not None:
        cursor = conn.cursor()
        for item in goods:
            cursor.execute(''' 
                INSERT INTO goods (title, price, shop, good_url, comment_num, comment_url)
                VALUES (%s, %s, %s, %s, %s, %s)
            ''', (item[0], item[1], item[2], item[3], item[4], item[5]))
        conn.commit()
        conn.close()


# 获取商品信息
def get_goods_info(word, page):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'
    }

    url = f'https://search.dangdang.com/?key={word}&act=input&page_index={page}'
    response = requests.get(url, headers=headers)
    response.encoding = 'gbk'
    html = etree.HTML(response.text)

    title = list(html.xpath('//*[@id="search_nature_rg"]/ul/li[*]/a/@title'))
    good_url = list(html.xpath('//*[@id="search_nature_rg"]/ul/li[*]/a/@href'))
    price = list(html.xpath('//*[@id="search_nature_rg"]/ul/li[*]/p[1]/span[1]/text()'))
    shop = list(html.xpath('//*[@id="search_nature_rg"]/ul/li[*]/p[5]/a/text()'))
    comment_num = list(html.xpath('//*[@id="search_nature_rg"]/ul/li[*]/p[4]/a/text()'))
    comment_url = list(html.xpath('//*[@id="search_nature_rg"]/ul/li[*]/p[4]/a/@href'))

    good_info = list(zip(title, price, shop, good_url, comment_num, comment_url))
    return good_info


# 价格转换函数，去除非数字字符并返回浮动数值
def parse_price(price_str):
    # 去除“￥”和“元”等非数字字符
    price_str = re.sub(r'[^\d.]', '', price_str)
    try:
        return float(price_str)
    except ValueError:
        return 0.0


# 获取按价格排序的商品信息
def get_goods_sorted_by_price(order='ASC'):
    conn = create_database_connection()
    if conn is not None:
        cursor = conn.cursor()
        try:
            # 使用 MySQL 的字符串处理函数来提取价格数字
            cursor.execute(f'''
                SELECT title, price, shop, good_url, comment_num, comment_url
                FROM goods
                ORDER BY CAST(
                    REPLACE(
                        REPLACE(
                            REPLACE(price, '¥', ''),
                            '元', ''
                        ),
                        ',', ''
                    ) AS DECIMAL(10,2)
                ) {'ASC' if order == 'ASC' else 'DESC'}
            ''')
            result = cursor.fetchall()
            conn.close()
            return result
        except Error as e:
            print(f"Error: {e}")
            conn.close()
    return []


# 获取按店铺分类的商品数量
def get_shop_statistics():
    conn = create_database_connection()
    if conn is not None:
        cursor = conn.cursor()
        try:
            cursor.execute('''
                SELECT shop, COUNT(*) as count
                FROM goods
                WHERE shop IS NOT NULL AND shop != ''
                GROUP BY shop
                ORDER BY count DESC
            ''')
            result = cursor.fetchall()
            conn.close()
            return result
        except Error as e:
            print(f"Error: {e}")
            conn.close()
    return []


# 获取按评论数排序的商品信息
def get_goods_sorted_by_comments():
    conn = create_database_connection()
    if conn is not None:
        cursor = conn.cursor()
        try:
            cursor.execute('''
                SELECT title, price, shop, good_url, comment_num, comment_url
                FROM goods
                ORDER BY CAST(REGEXP_REPLACE(comment_num, '[^0-9]', '') AS UNSIGNED) DESC
            ''')
            result = cursor.fetchall()
            conn.close()
            return result
        except Error as e:
            print(f"Error: {e}")
            conn.close()
    return []


# 清空数据库中的商品数据
def clear_database():
    conn = create_database_connection()
    if conn is not None:
        cursor = conn.cursor()
        try:
            cursor.execute('TRUNCATE TABLE goods')
            conn.commit()
            conn.close()
            return True
        except Error as e:
            print(f"Error: {e}")
            conn.rollback()
            conn.close()
            return False
    return False


# PyQt5 窗口类
class MainWindow(QWidget):
    def __init__(self):
        super().__init__()
        
        # 设置窗口基本属性
        self.setWindowTitle("智能商品搜索系统")
        self.setGeometry(200, 200, 1000, 700)
        self.setStyleSheet("""
            QWidget {
                background-color: #1e1e2e;
                color: #ffffff;
                font-family: 'Segoe UI', '微软雅黑';
            }
            QLineEdit {
                padding: 8px;
                border: 2px solid #3daee9;
                border-radius: 5px;
                background-color: #2d2d44;
                color: #ffffff;
                font-size: 14px;
            }
            QLineEdit:focus {
                border: 2px solid #16a085;
            }
            QPushButton {
                padding: 8px 15px;
                background-color: #3daee9;
                border: none;
                border-radius: 5px;
                color: white;
                font-weight: bold;
                font-size: 14px;
            }
            QPushButton:hover {
                background-color: #16a085;
            }
            QPushButton:pressed {
                background-color: #2980b9;
            }
            QTableWidget {
                background-color: #2d2d44;
                border: 1px solid #3daee9;
                border-radius: 5px;
                gridline-color: #3daee9;
            }
            QTableWidget::item {
                padding: 5px;
            }
            QTableWidget::item:selected {
                background-color: #16a085;
            }
            QHeaderView::section {
                background-color: #1e1e2e;
                padding: 5px;
                border: 1px solid #3daee9;
                font-weight: bold;
            }
            QComboBox {
                padding: 5px;
                border: 2px solid #3daee9;
                border-radius: 5px;
                background-color: #2d2d44;
                color: white;
            }
            QComboBox::drop-down {
                border: none;
            }
            QComboBox::down-arrow {
                image: url(down_arrow.png);
                width: 12px;
                height: 12px;
            }
        """)

        # 主布局修改
        self.layout = QVBoxLayout()
        self.layout.setSpacing(15)
        self.layout.setContentsMargins(20, 20, 20, 20)

        # 创建顶部搜索框容器
        search_container = QFrame()
        search_container.setObjectName("searchContainer")
        search_container.setStyleSheet("""
            #searchContainer {
                background-color: #2d2d44;
                border-radius: 10px;
                padding: 10px;
            }
        """)
        
        # 添加阴影效果
        shadow = QGraphicsDropShadowEffect()
        shadow.setBlurRadius(15)
        shadow.setColor(QColor(0, 0, 0, 80))
        shadow.setOffset(0, 0)
        search_container.setGraphicsEffect(shadow)

        # 搜索部分布局
        search_layout = QHBoxLayout(search_container)
        search_layout.setContentsMargins(10, 10, 10, 10)
        
        # 修改搜索框和按钮的样式
        self.label_word = QLabel("搜索词:")
        self.entry_word = QLineEdit(self)
        self.entry_word.setPlaceholderText("输入商品关���词")
        self.label_page = QLabel("页码:")
        self.entry_page = QLineEdit(self)
        self.entry_page.setPlaceholderText("输入页码")
        self.search_button = QPushButton("开始搜索", self)
        self.search_button.setCursor(Qt.PointingHandCursor)
        
        # 添加搜索动画效果
        self.search_button.clicked.connect(self.animate_search)

        search_layout.addWidget(self.label_word)
        search_layout.addWidget(self.entry_word)
        search_layout.addWidget(self.label_page)
        search_layout.addWidget(self.entry_page)
        search_layout.addWidget(self.search_button)

        self.layout.addWidget(search_container)

        # 表格容器
        table_container = QFrame()
        table_container.setObjectName("tableContainer")
        table_container.setStyleSheet("""
            #tableContainer {
                background-color: #2d2d44;
                border-radius: 10px;
                padding: 10px;
            }
        """)
        
        table_layout = QVBoxLayout(table_container)
        self.table_widget = QTableWidget(self)
        table_layout.addWidget(self.table_widget)
        
        # 添加表格阴影
        table_shadow = QGraphicsDropShadowEffect()
        table_shadow.setBlurRadius(15)
        table_shadow.setColor(QColor(0, 0, 0, 80))
        table_shadow.setOffset(0, 0)
        table_container.setGraphicsEffect(table_shadow)

        self.layout.addWidget(table_container)

        # 按钮容器
        button_container = QFrame()
        button_container.setObjectName("buttonContainer")
        button_container.setStyleSheet("""
            #buttonContainer {
                background-color: #2d2d44;
                border-radius: 10px;
                padding: 10px;
            }
        """)
        
        button_layout = QHBoxLayout(button_container)
        
        # 修改所有按钮样式
        self.category_button = QPushButton("按店铺分类", self)
        self.sort_button = QPushButton("按评论数排序", self)
        self.price_sort_button = QPushButton("按价格从低到高排序", self)
        self.clear_button = QPushButton("清空数据库", self)
        self.stats_button = QPushButton("数据统计", self)
        self.history_button = QPushButton("历史记录", self)
        
        # 添加价格排序状态标志
        self.price_sort_ascending = True  # True表示从低到高
        
        # 连接按钮点击事件
        self.category_button.clicked.connect(self.show_shop_statistics)
        self.sort_button.clicked.connect(self.sort_goods_by_comments)
        self.price_sort_button.clicked.connect(self.sort_goods_by_price)
        self.clear_button.clicked.connect(self.clear_db)
        self.stats_button.clicked.connect(self.show_statistics)
        self.history_button.clicked.connect(self.show_history)
        
        # 为所有按钮添加鼠标悬停效果
        for button in [self.category_button, self.sort_button, 
                      self.price_sort_button, self.clear_button, self.stats_button, self.history_button]:
            button.setCursor(Qt.PointingHandCursor)
            
        button_layout.addWidget(self.category_button)
        button_layout.addWidget(self.sort_button)
        button_layout.addWidget(self.price_sort_button)
        button_layout.addWidget(self.clear_button)
        button_layout.addWidget(self.stats_button)
        button_layout.addWidget(self.history_button)
        
        self.layout.addWidget(button_container)
        
        # 设置主布局
        self.setLayout(self.layout)
        
        # 初始化数据库
        create_table_if_not_exists()

    # 搜索商品并显示结果
    def search_goods(self):
        word = self.entry_word.text()
        page = self.entry_page.text()

        if not word or not page:
            QMessageBox.warning(self, "输入错误", "请填写所有信息！")
            return

        try:
            page = int(page)
            # 获取商品信息
            goods = get_goods_info(word, page)

            if goods:
                # 将商品信息插入到数据库
                insert_goods_to_db(goods)
                # 保存搜索历史
                save_search_history(word, page, len(goods))
                # 更新表格
                self.update_table(goods)
            else:
                QMessageBox.information(self, "没有结果", "未找到相关商品")
        except ValueError:
            QMessageBox.warning(self, "输入错误", "页码应为数字！")

    def update_table(self, goods):
        # 设置表格的行数和列数
        self.table_widget.setRowCount(len(goods))
        self.table_widget.setColumnCount(6)

        # 设置表头
        self.table_widget.setHorizontalHeaderLabels(["标题", "价格", "店铺", "商品链接", "评论数量", "评论链接"])

        # 填充表格数据
        for row, item in enumerate(goods):
            for col, data in enumerate(item):
                self.table_widget.setItem(row, col, QTableWidgetItem(data))

        # 自动调整列宽
        self.table_widget.resizeColumnsToContents()

    # 示按店铺分的商品数量
    def show_shop_statistics(self):
        shop_stats = get_shop_statistics()

        if shop_stats:
            # 创建新的表格显示店铺统计
            self.table_widget.setRowCount(len(shop_stats))
            self.table_widget.setColumnCount(2)

            # 设置表头
            self.table_widget.setHorizontalHeaderLabels(["店铺", "商品数量"])

            # 填充表格数据
            for row, (shop, count) in enumerate(shop_stats):
                self.table_widget.setItem(row, 0, QTableWidgetItem(shop))
                self.table_widget.setItem(row, 1, QTableWidgetItem(str(count)))

            # 自动调整列宽
            self.table_widget.resizeColumnsToContents()
        else:
            QMessageBox.information(self, "无店铺数据", "没有找到店铺数据！")

    # 按评论数排序商品并更新显示
    def sort_goods_by_comments(self):
        sorted_goods = get_goods_sorted_by_comments()

        if sorted_goods:
            # 更新表格，按评论数排序
            self.update_table(sorted_goods)
        else:
            QMessageBox.information(self, "没有结果", "未找到商品数据！")

    # 修改按价格排序的方法
    def sort_goods_by_price(self):
        try:
            # 根据当前状态决定排序方式
            order = 'ASC' if self.price_sort_ascending else 'DESC'
            sorted_goods = get_goods_sorted_by_price(order)

            if sorted_goods:
                # 更新表格，按价格排序
                self.update_table(sorted_goods)
                
                # 切换排序状态和按钮文本
                self.price_sort_ascending = not self.price_sort_ascending
                self.price_sort_button.setText(
                    "按价格从低到高排序" if self.price_sort_ascending else "按价格从高到低排序"
                )
            else:
                QMessageBox.information(self, "没有结果", "未找到商品数据！")
        except Exception as e:
            QMessageBox.warning(self, "排序错误", f"排序过程中出现错误: {str(e)}")

    # 清空数据库操作
    def clear_db(self):
        reply = QMessageBox.question(self, "清空数据库", "你确定要清空所有商品数据吗？", QMessageBox.Yes | QMessageBox.No)
        if reply == QMessageBox.Yes:
            if clear_database():
                QMessageBox.information(self, "成功", "数据库已清空！")
                self.table_widget.setRowCount(0)  # 清空表格
            else:
                QMessageBox.warning(self, "失败", "清空数据库失败，请稍后再试！")

    def animate_search(self):
        # 创建搜索按钮点击动画
        self.search_animation = QPropertyAnimation(self.search_button, b"geometry")
        self.search_animation.setDuration(100)
        self.search_animation.setEasingCurve(QEasingCurve.OutBounce)
        
        current_geometry = self.search_button.geometry()
        
        # 设置动画关键帧
        self.search_animation.setStartValue(current_geometry)
        smaller_geometry = current_geometry.adjusted(2, 2, -2, -2)
        self.search_animation.setKeyValueAt(0.5, smaller_geometry)
        self.search_animation.setEndValue(current_geometry)
        
        # 连接动画完成信号到搜索函数
        self.search_animation.finished.connect(self.search_goods)
        
        # 只开始动画，搜索会在动画完成后执行
        self.search_animation.start()

    def show_statistics(self):
        self.stats_window = DataVisualizationWindow(self)
        self.stats_window.show()

    def show_history(self):
        history_window = SearchHistoryWindow(self)
        history_window.show()


class DataVisualizationWindow(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("商品数据可视化")
        self.setGeometry(300, 300, 1200, 800)
        # 设置无边框窗口，这样看起来更现代
        self.setWindowFlags(Qt.FramelessWindowHint)
        
        # 添加鼠标跟踪
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.pressing = False
        self.start_point = None
        
        # 修改窗口样式
        self.setStyleSheet("""
            QWidget {
                background-color: #2c3e50;  /* 更改背景色 */
                color: #ecf0f1;
                border-radius: 15px;
            }
            QPushButton {
                background-color: #3498db;
                border: none;
                border-radius: 5px;
                padding: 10px;
                color: white;
                font-weight: bold;
            }
            QPushButton:hover {
                background-color: #2980b9;
            }
            #titleBar {
                background-color: #34495e;  /* 更改标题栏背景色 */
                border-top-left-radius: 15px;
                border-top-right-radius: 15px;
                padding: 10px;
            }
            #closeButton {
                background-color: #e74c3c;
                min-width: 20px;
                max-width: 20px;
                min-height: 20px;
                max-height: 20px;
                border-radius: 10px;
            }
            #closeButton:hover {
                background-color: #c0392b;
            }
        """)
        
        # 创建主布局
        layout = QVBoxLayout(self)
        layout.setSpacing(0)
        layout.setContentsMargins(0, 0, 0, 0)
        
        # 创建标题栏
        title_bar = QWidget()
        title_bar.setObjectName("titleBar")
        title_bar_layout = QHBoxLayout(title_bar)
        
        # 创建标题
        title = QLabel("商品数据分析统计")
        title.setStyleSheet("""
            font-size: 24px;
            color: #3498db;
            font-weight: bold;
        """)
        title.setAlignment(Qt.AlignCenter)
        
        # 创建关闭按钮
        close_button = QPushButton()
        close_button.setObjectName("closeButton")
        close_button.clicked.connect(self.close)
        close_button.setCursor(Qt.PointingHandCursor)
        
        title_bar_layout.addWidget(title)
        title_bar_layout.addWidget(close_button)
        
        layout.addWidget(title_bar)
        
        # 创建图表容器
        charts_layout = QHBoxLayout()
        charts_layout.setContentsMargins(20, 20, 20, 20)
        
        # 创建左侧价格分布图表
        self.price_chart_view = self.create_price_distribution_chart()
        charts_layout.addWidget(self.price_chart_view)
        
        # 创建右侧店铺分布饼图
        self.shop_chart_view = self.create_shop_distribution_chart()
        charts_layout.addWidget(self.shop_chart_view)
        
        layout.addLayout(charts_layout)
        
        # 创建底部评论分布图表
        self.comment_chart_view = self.create_comment_distribution_chart()
        layout.addWidget(self.comment_chart_view)
        
        # 添加刷新按钮
        refresh_btn = QPushButton("刷新数据")
        refresh_btn.clicked.connect(self.refresh_charts)
        refresh_btn.setCursor(Qt.PointingHandCursor)
        layout.addWidget(refresh_btn, alignment=Qt.AlignCenter)
        
        # 设置定时刷新
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.refresh_charts)
        self.timer.start(30000)  # 每30秒刷新一次

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.pressing = True
            self.start_point = event.globalPos()
            self.window_point = self.frameGeometry().topLeft()

    def mouseMoveEvent(self, event):
        if self.pressing:
            move_point = event.globalPos() - self.start_point
            self.move(self.window_point + move_point)

    def mouseReleaseEvent(self, event):
        self.pressing = False

    def create_price_distribution_chart(self):
        chart = QChart()
        chart.setTitle("商品价格分布")
        chart.setAnimationOptions(QChart.SeriesAnimations)
        
        # 修改图表背景和样式
        gradient = QLinearGradient(0, 0, 0, 300)
        gradient.setColorAt(0, QColor("#34495e"))
        gradient.setColorAt(1, QColor("#2c3e50"))
        chart.setBackgroundBrush(gradient)
        
        # 设置标题样式
        chart.setTitleBrush(QColor("#ecf0f1"))
        chart.setTitleFont(QFont("Arial", 12, QFont.Bold))
        
        # 获取价格数据
        price_ranges = self.get_price_distribution()
        
        # 创建柱状图数据并设置颜色
        bar_set = QBarSet("价格区间")
        bar_set.setColor(QColor("#3498db"))  # 设置柱状图颜色
        for count in price_ranges.values():
            bar_set.append(count)
        
        series = QBarSeries()
        series.append(bar_set)
        chart.addSeries(series)
        
        # 设置坐标轴
        axis_x = QBarCategoryAxis()
        axis_x.append(list(price_ranges.keys()))
        axis_x.setLabelsColor(QColor("#ecf0f1"))  # 设置x轴标签颜色
        chart.addAxis(axis_x, Qt.AlignBottom)
        series.attachAxis(axis_x)
        
        axis_y = QValueAxis()
        axis_y.setLabelsColor(QColor("#ecf0f1"))  # 设置y轴标签颜色
        axis_y.setGridLineColor(QColor("#34495e"))  # 设置网格线颜色
        chart.addAxis(axis_y, Qt.AlignLeft)
        series.attachAxis(axis_y)
        
        chart_view = QChartView(chart)
        chart_view.setRenderHint(QPainter.Antialiasing)
        return chart_view
    
    def create_shop_distribution_chart(self):
        chart = QChart()
        chart.setTitle("店铺分布")
        chart.setAnimationOptions(QChart.SeriesAnimations)
        
        # 修改图表背景和样式
        gradient = QLinearGradient(0, 0, 0, 300)
        gradient.setColorAt(0, QColor("#34495e"))
        gradient.setColorAt(1, QColor("#2c3e50"))
        chart.setBackgroundBrush(gradient)
        
        # 设置标题样式
        chart.setTitleBrush(QColor("#ecf0f1"))
        chart.setTitleFont(QFont("Arial", 12, QFont.Bold))
        
        series = QPieSeries()
        shop_stats = get_shop_statistics()
        
        # 设置饼图颜色
        colors = ["#3498db", "#e74c3c", "#2ecc71", "#f1c40f", "#9b59b6", 
                 "#1abc9c", "#e67e22", "#34495e", "#16a085", "#c0392b"]
        
        for i, (shop, count) in enumerate(shop_stats):
            slice = series.append(shop, count)
            slice.setLabelVisible(True)
            slice.setColor(QColor(colors[i % len(colors)]))  # 循环使用颜色
            slice.setLabelColor(QColor("#ecf0f1"))
        
        chart.addSeries(series)
        
        chart_view = QChartView(chart)
        chart_view.setRenderHint(QPainter.Antialiasing)
        return chart_view
    
    def create_comment_distribution_chart(self):
        chart = QChart()
        chart.setTitle("评论数量分布")
        chart.setAnimationOptions(QChart.SeriesAnimations)
        
        # 修改图表背景和样式
        gradient = QLinearGradient(0, 0, 0, 300)
        gradient.setColorAt(0, QColor("#34495e"))
        gradient.setColorAt(1, QColor("#2c3e50"))
        chart.setBackgroundBrush(gradient)
        
        # 设置标题样式
        chart.setTitleBrush(QColor("#ecf0f1"))
        chart.setTitleFont(QFont("Arial", 12, QFont.Bold))
        
        comment_ranges = self.get_comment_distribution()
        
        # 创建柱状图数据并设置颜色
        bar_set = QBarSet("评论数量")
        bar_set.setColor(QColor("#2ecc71"))  # 设置柱状图颜色
        for count in comment_ranges.values():
            bar_set.append(count)
        
        series = QBarSeries()
        series.append(bar_set)
        chart.addSeries(series)
        
        # 设置坐标轴
        axis_x = QBarCategoryAxis()
        axis_x.append(list(comment_ranges.keys()))
        axis_x.setLabelsColor(QColor("#ecf0f1"))
        chart.addAxis(axis_x, Qt.AlignBottom)
        series.attachAxis(axis_x)
        
        axis_y = QValueAxis()
        axis_y.setLabelsColor(QColor("#ecf0f1"))
        axis_y.setGridLineColor(QColor("#34495e"))
        chart.addAxis(axis_y, Qt.AlignLeft)
        series.attachAxis(axis_y)
        
        chart_view = QChartView(chart)
        chart_view.setRenderHint(QPainter.Antialiasing)
        return chart_view
    
    def get_price_distribution(self):
        conn = create_database_connection()
        if conn is not None:
            cursor = conn.cursor()
            ranges = {
                "0-50": 0,
                "51-100": 0,
                "101-200": 0,
                "201-500": 0,
                "500+": 0
            }
            
            cursor.execute("SELECT price FROM goods")
            prices = cursor.fetchall()
            
            for price in prices:
                try:
                    price_value = float(re.sub(r'[^\d.]', '', price[0]))
                    if price_value <= 50:
                        ranges["0-50"] += 1
                    elif price_value <= 100:
                        ranges["51-100"] += 1
                    elif price_value <= 200:
                        ranges["101-200"] += 1
                    elif price_value <= 500:
                        ranges["201-500"] += 1
                    else:
                        ranges["500+"] += 1
                except ValueError:
                    continue
                    
            conn.close()
            return ranges
        return {}
    
    def get_comment_distribution(self):
        conn = create_database_connection()
        if conn is not None:
            cursor = conn.cursor()
            ranges = {
                "0-100": 0,
                "101-500": 0,
                "501-1000": 0,
                "1001-5000": 0,
                "5000+": 0
            }
            
            cursor.execute("SELECT comment_num FROM goods")
            comments = cursor.fetchall()
            
            for comment in comments:
                try:
                    comment_value = int(re.sub(r'[^\d]', '', comment[0]))
                    if comment_value <= 100:
                        ranges["0-100"] += 1
                    elif comment_value <= 500:
                        ranges["101-500"] += 1
                    elif comment_value <= 1000:
                        ranges["501-1000"] += 1
                    elif comment_value <= 5000:
                        ranges["1001-5000"] += 1
                    else:
                        ranges["5000+"] += 1
                except ValueError:
                    continue
                    
            conn.close()
            return ranges
        return {}
    
    def refresh_charts(self):
        # 刷新价格分布图
        price_chart = self.price_chart_view.chart()
        price_chart.removeAllSeries()
        price_ranges = self.get_price_distribution()
        price_series = QBarSeries()
        price_bar_set = QBarSet("价格区间")
        price_bar_set.setColor(QColor("#3498db"))  # 保持柱状图颜色
        for count in price_ranges.values():
            price_bar_set.append(count)
        price_series.append(price_bar_set)
        price_chart.addSeries(price_series)
        
        # 重新设置价格图表的坐标轴
        axis_x = QBarCategoryAxis()
        axis_x.append(list(price_ranges.keys()))
        axis_x.setLabelsColor(QColor("#ecf0f1"))  # 保持x轴标签颜色
        price_chart.addAxis(axis_x, Qt.AlignBottom)
        price_series.attachAxis(axis_x)
        
        axis_y = QValueAxis()
        axis_y.setLabelsColor(QColor("#ecf0f1"))  # 保持y轴标签颜色
        axis_y.setGridLineColor(QColor("#34495e"))  # 保持网格线颜色
        price_chart.addAxis(axis_y, Qt.AlignLeft)
        price_series.attachAxis(axis_y)

        # 刷新店铺分布图
        shop_chart = self.shop_chart_view.chart()
        shop_chart.removeAllSeries()
        shop_series = QPieSeries()
        shop_stats = get_shop_statistics()
        
        # 保持饼图颜色
        colors = ["#3498db", "#e74c3c", "#2ecc71", "#f1c40f", "#9b59b6", 
                 "#1abc9c", "#e67e22", "#34495e", "#16a085", "#c0392b"]
        
        for i, (shop, count) in enumerate(shop_stats):
            slice = shop_series.append(shop, count)
            slice.setLabelVisible(True)
            slice.setColor(QColor(colors[i % len(colors)]))  # 保持饼图颜色
            slice.setLabelColor(QColor("#ecf0f1"))  # 保持标签颜色
        shop_chart.addSeries(shop_series)

        # 刷新评论分布图
        comment_chart = self.comment_chart_view.chart()
        comment_chart.removeAllSeries()
        comment_ranges = self.get_comment_distribution()
        comment_series = QBarSeries()
        comment_bar_set = QBarSet("评论数量")
        comment_bar_set.setColor(QColor("#2ecc71"))  # 保持柱状图颜色
        for count in comment_ranges.values():
            comment_bar_set.append(count)
        comment_series.append(comment_bar_set)
        comment_chart.addSeries(comment_series)
        
        # 重新设置评论图表的坐标轴
        comment_axis_x = QBarCategoryAxis()
        comment_axis_x.append(list(comment_ranges.keys()))
        comment_axis_x.setLabelsColor(QColor("#ecf0f1"))  # 保持x轴标签颜色
        comment_chart.addAxis(comment_axis_x, Qt.AlignBottom)
        comment_series.attachAxis(comment_axis_x)
        
        comment_axis_y = QValueAxis()
        comment_axis_y.setLabelsColor(QColor("#ecf0f1"))  # 保持y轴标签颜色
        comment_axis_y.setGridLineColor(QColor("#34495e"))  # 保持网格线颜色
        comment_chart.addAxis(comment_axis_y, Qt.AlignLeft)
        comment_series.attachAxis(comment_axis_y)
        
        # 重新设置所有图表的标题样式
        for chart in [price_chart, shop_chart, comment_chart]:
            chart.setTitleBrush(QColor("#ecf0f1"))
            chart.setTitleFont(QFont("Arial", 12, QFont.Bold))


# 添加历史记录窗口类
class SearchHistoryWindow(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("搜索历史记录")
        self.setGeometry(300, 300, 800, 600)
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        
        # 设置窗口样式
        self.setStyleSheet("""
            QWidget {
                background-color: #2c3e50;
                color: #ecf0f1;
                border-radius: 15px;
            }
            QTableWidget {
                background-color: #34495e;
                border: none;
                border-radius: 10px;
                gridline-color: #3498db;
            }
            QTableWidget::item {
                padding: 5px;
                border-bottom: 1px solid #3498db;
            }
            QTableWidget::item:selected {
                background-color: #3498db;
            }
            QPushButton {
                background-color: #3498db;
                border: none;
                border-radius: 5px;
                padding: 8px;
                color: white;
            }
            QPushButton:hover {
                background-color: #2980b9;
            }
            #titleBar {
                background-color: #34495e;
                border-top-left-radius: 15px;
                border-top-right-radius: 15px;
            }
        """)
        
        # 创建主布局
        layout = QVBoxLayout(self)
        layout.setSpacing(0)
        layout.setContentsMargins(0, 0, 0, 0)
        
        # 创建标题栏
        title_bar = QWidget()
        title_bar.setObjectName("titleBar")
        title_bar_layout = QHBoxLayout(title_bar)
        
        title = QLabel("搜索历史记录")
        title.setStyleSheet("font-size: 18px; font-weight: bold;")
        close_button = QPushButton("×")
        close_button.setStyleSheet("""
            QPushButton {
                background-color: #e74c3c;
                min-width: 30px;
                max-width: 30px;
                min-height: 30px;
                max-height: 30px;
                border-radius: 15px;
                font-size: 20px;
            }
            QPushButton:hover {
                background-color: #c0392b;
            }
        """)
        close_button.clicked.connect(self.close)
        
        title_bar_layout.addWidget(title)
        title_bar_layout.addWidget(close_button)
        
        layout.addWidget(title_bar)
        
        # 创建表格
        self.table = QTableWidget()
        self.table.setColumnCount(4)
        self.table.setHorizontalHeaderLabels(["搜索关键词", "搜索时间", "页码", "结果数量"])
        self.table.horizontalHeader().setStretchLastSection(True)
        self.table.verticalHeader().setVisible(False)
        
        layout.addWidget(self.table)
        
        # 添加刷新按钮
        refresh_button = QPushButton("刷新历史记录")
        refresh_button.clicked.connect(self.load_history)
        layout.addWidget(refresh_button, alignment=Qt.AlignCenter)
        
        # 加载历史记录
        self.load_history()
        
        # 添加鼠标拖动支持
        self.pressing = False
        self.start_point = None

    def load_history(self):
        history = get_search_history()
        self.table.setRowCount(len(history))
        
        for row, (word, time, page, count) in enumerate(history):
            self.table.setItem(row, 0, QTableWidgetItem(word))
            self.table.setItem(row, 1, QTableWidgetItem(str(time)))
            self.table.setItem(row, 2, QTableWidgetItem(str(page)))
            self.table.setItem(row, 3, QTableWidgetItem(str(count)))
        
        self.table.resizeColumnsToContents()

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.pressing = True
            self.start_point = event.globalPos()
            self.window_point = self.frameGeometry().topLeft()

    def mouseMoveEvent(self, event):
        if self.pressing:
            move_point = event.globalPos() - self.start_point
            self.move(self.window_point + move_point)

    def mouseReleaseEvent(self, event):
        self.pressing = False


# 添加保存历史记录的函数
def save_search_history(word, page, results_count):
    conn = create_database_connection()
    if conn is not None:
        cursor = conn.cursor()
        cursor.execute('''
            INSERT INTO search_history (search_word, search_time, page_num, results_count)
            VALUES (%s, NOW(), %s, %s)
        ''', (word, page, results_count))
        conn.commit()
        conn.close()


# 获取历史记录的函数
def get_search_history():
    conn = create_database_connection()
    if conn is not None:
        cursor = conn.cursor()
        cursor.execute('''
            SELECT search_word, search_time, page_num, results_count
            FROM search_history
            ORDER BY search_time DESC
            LIMIT 100
        ''')
        result = cursor.fetchall()
        conn.close()
        return result
    return []


# 运行程序
def run_app():
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    run_app()
